package exec

import (
	"hundsun.com/hsl/hschain/common/types"
	execcomm "hundsun.com/hsl/hschain/executor/common"
	"hundsun.com/hsl/hschain/protos/execute"
	"hundsun.com/hsl/hschain/protos/manage"
)

// Execution 执行节点接口
type Execution interface {
	Run(ctx *execcomm.ExecContent, gtx *execute.GroupedTransaction) error
}

// ExecutionFactory 执行方法工厂
var ExecutionFactory = map[string]func(uint32, uint32, *manage.ManageFlowProposal, *manage.ExecProperties) Execution{}

// RegisterExecution 注册执行方法
func RegisterExecution(name string, create func(uint32, uint32, *manage.ManageFlowProposal, *manage.ExecProperties) Execution) {
	if _, ok := ExecutionFactory[name]; ok {
		panic("execution already existed" + name)
	}
	ExecutionFactory[name] = create
}

// LoadExecution 加载执行方法
func LoadExecution(name string) (func(uint32, uint32, *manage.ManageFlowProposal, *manage.ExecProperties) Execution, error) {
	if create, ok := ExecutionFactory[name]; ok {
		return create, nil
	}
	return nil, types.ErrNotFound
}

// ExecutionAdaptor 执行节点适配
type ExecutionAdaptor struct {
	flowID     uint32
	flowStep   uint32
	proposal   *manage.ManageFlowProposal
	properties *manage.ExecProperties
}

// InitAdaptor 初始化
func (ea *ExecutionAdaptor) InitAdaptor(id, step uint32, proposal *manage.ManageFlowProposal, properties *manage.ExecProperties) {
	ea.flowID = id
	ea.flowStep = step
	ea.proposal = proposal
	ea.properties = properties
}

// GetFlowID 获取流程ID
func (ea *ExecutionAdaptor) GetFlowID() uint32 {
	return ea.flowID
}

// GetFlowStep 获取步骤信息
func (ea *ExecutionAdaptor) GetFlowStep() uint32 {
	return ea.flowStep
}

// GetProposal 获取提案
func (ea *ExecutionAdaptor) GetProposal() *manage.ManageFlowProposal {
	return ea.proposal
}

// GetProperties 获取配置选项
func (ea *ExecutionAdaptor) GetProperties() *manage.ExecProperties {
	return ea.properties
}
